package com.woniu.cms.psm.core.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniu.cms.psm.core.constant.PositionNameConstant;
import com.woniu.cms.psm.core.constant.ProjectCategoryConstant;
import com.woniu.cms.psm.core.constant.ProvinceConstant;
import com.woniu.cms.psm.core.constant.SerialNum;
import com.woniu.cms.psm.core.entity.Attachment;
import com.woniu.cms.psm.core.entity.Message;
import com.woniu.cms.psm.core.entity.PmFeasibility;
import com.woniu.cms.psm.core.mapper.PmFeasibilityMapper;
import com.woniu.cms.psm.core.service.IAttachmentService;
import com.woniu.cms.psm.core.service.IMessageService;
import com.woniu.cms.psm.core.service.IPmFeasibilityService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniu.cms.psm.core.vo.FeasibilityVo;
import com.woniu.cms.psm.core.vo.FeasibilityWithAttachmentVo;
import com.woniu.cms.psm.core.vo.PageVo;
import com.woniu.common.feign.AuthClient;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.text.DecimalFormat;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author lilili
 * @since 2022-09-16
 */
@Service
public class PmFeasibilityServiceImpl extends ServiceImpl<PmFeasibilityMapper, PmFeasibility> implements IPmFeasibilityService {
    @Resource
    private PmFeasibilityMapper feasibilityMapper;
    @Resource
    private IMessageService messageService;
    @Resource
    private AuthClient authClient;
    @Resource
    private IAttachmentService attachmentService;

    @Transactional
    @Override
    public PageVo<FeasibilityVo> getPage(Integer pageNo, Integer pageSize) {
        Page<FeasibilityVo> page = new Page(pageNo, pageSize);
        FeasibilityVo feasibilityVo = new FeasibilityVo();
        Page<FeasibilityVo> ipage = feasibilityMapper.selectFeasibilityVoPage(page, feasibilityVo);
        List<FeasibilityVo> list = ipage.getRecords();

        PageVo<FeasibilityVo> PageVo = new PageVo().setObjs((list))
                .setCurrent(ipage.getCurrent())
                .setPages(ipage.getPages())
                .setSize(ipage.getSize())
                .setTotal(ipage.getTotal())
                .setHasPrevious(ipage.hasPrevious())
                .setHasNext(ipage.hasNext());


        return PageVo;

    }

    @Transactional
    @Override
    public boolean delete(Integer[] ids) {
        int i = feasibilityMapper.deleteBatchIds(Arrays.asList(ids));
        if(i == 0) {
            throw new RuntimeException("删除立项表单失败");
        }
        return true;
    }

    @Transactional
    @Override
    public boolean add(PmFeasibility feasibility, List<Integer> ids) {
        //首先无论传过来的id是多少都得置为空
        feasibility.setId(null);
        //立项完项目状态为正常施工
        feasibility.setProjectStatus(0);
        //项目编号不生成,审批后才能生成
        feasibility.setProjectId(null);
        //判断传过来的项目类别是否为形象工程，默认是一般工程
        String projectCategory = feasibility.getProjectCategory();
        if(ProjectCategoryConstant.APPERARANCE.getType().equals(projectCategory)){
            //如果是形象工程自动生成形象工程表
            log.warn("调用形象工程生成形象工程表");
        }
        feasibilityMapper.insert(feasibility);


        //立项表和附件表结合
        //文件上传完后，返回附件id，立项表添加时给附件id，再在此处建立联系。
        ids.forEach(e ->{
            attachmentService.update(new LambdaUpdateWrapper<Attachment>().set(Attachment::getObjId, feasibility.getId()).eq(Attachment::getId, e));
        });

        return true;
    }

    @Transactional
    @Override
    public boolean check(Integer id, String userName) {
        //生成项目编号
        int year = LocalDate.now().getYear();
        DecimalFormat decimalFormat = new DecimalFormat("00000");
        String format = decimalFormat.format(id);
        if(id > 99999){
            String s = String.valueOf(id);
            format = s.substring(s.length() -5, s.length());
        }
        //前缀+四位年份+五位流水号
        String proId = SerialNum.SERIALNUM.getNum() + year + format;

        //改变审批状态和项目编号
        LambdaUpdateWrapper<PmFeasibility> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(PmFeasibility::getApplyStatus, 1)
                .set(PmFeasibility::getProjectId, proId)
                .eq(PmFeasibility::getId, id);
        int update = feasibilityMapper.update(null, updateWrapper);
        if(update == 0){
            throw new RuntimeException("审批立项失败");
        }

        //1.审批通过后判断是否位本地项目，若不是则发送传阅给预控费用者
        PmFeasibility feasibility = this.getById(id);
        String region = feasibility.getRegion();
        if(StringUtils.isEmpty(region)){
            throw new RuntimeException("地址不能为空");
        }
        if(!region.contains(ProvinceConstant.PROVINCE_CURRENT.getName())){
            //不是本地项目,发送传阅
            //需要一个username
            //根据职位名称返回用户id,调用微服务
            List<String> names = authClient.getUserByPositionName(PositionNameConstant.F_PRECONTROL.getName()).getData();
            if(CollectionUtils.isEmpty(names)){
                throw new RuntimeException("预控通知发送失败");
            }
            for (String  name : names) {
                Message message = new Message();
                message.setId(null).setMessage("有预控项目需要进行预控管理").setAcceptorName(name).setProviderName(userName).setStatus(0);
                messageService.save(message);
            }
        }
        //2.发送传阅给项目管理员
        List<String> names = authClient.getUserByPositionName(PositionNameConstant.F_PROJECT_MANAGER.getName()).getData();
        if(CollectionUtils.isEmpty(names)){
            throw new RuntimeException("项目管理通知发送失败");
        }
        for (String name : names) {
            Message message = new Message();
            message.setId(null).setMessage("需要去进行项目管理").setAcceptorName(name).setProviderName(userName).setStatus(0);
            messageService.save(message);
        }


        return true;
    }

    @Override
    public FeasibilityWithAttachmentVo look(Integer id) {
        PmFeasibility feasibility = this.getById(id);
        List<Attachment> list = attachmentService.list(new LambdaQueryWrapper<Attachment>().eq(Attachment::getObjId, id));
        return new FeasibilityWithAttachmentVo().setFeasibility(feasibility).setAttachmentList(list);
    }
}
